# -*- coding: utf-8 -*-
# (c) 2015 Mikel Arregi - AvanzOSC
# (c) 2015 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import _, api, exceptions, fields, models
import odoo.addons.decimal_precision as dp
from odoo.tools.float_utils import float_compare


class movepickQuants(models.TransientModel):
    _name = 'move.pick.quants'

    # @api.multi
    # @api.constrains('quants_lines')
    # def check_qty(self):
    #     precision_digits = self.env[
    #         'decimal.precision'].precision_get('Product Unit of Measure')
    #     move = self.env['stock.move'].browse(self.env.context['active_id'])
    #     for record in self.filtered('quants_lines'):
    #         if float_compare(record.lines_qty, move.product_qty,
    #                          precision_digits=precision_digits) > 0:
    #             raise exceptions.UserError(
    #                 _(u'挑选的数量必须不能超过原始需求数量！'))

    @api.depends('quants_lines', 'quants_lines.qty')
    def _compute_qties(self):
        move = self.move_id

        lines_qty = sum(quant_line.qty for quant_line in self.quants_lines
                        if quant_line.selected)
        self.lines_qty = lines_qty
        self.move_qty = move.product_qty - lines_qty

    name = fields.Char(string=u'名称')
    move_id = fields.Many2one("stock.move")
    lines_qty = fields.Float(
        string=u'保留数', compute='_compute_qties',
        digits=dp.get_precision('Product Unit of Measure'))
    move_qty = fields.Float(string=u'剩余数', compute='_compute_qties',
                            digits=dp.get_precision('Product Unit of Measure'))
    quants_lines = fields.One2many('move.pick.quants.lines',
                                   'move_wizard', string=u'库存份')
    location_search_key = fields.Char(string=u"库位")
    track_no_search_key = fields.Char(string=u"追踪号")

    @api.multi
    def move_quants(self):
        move = self.move_id
        move.picking_id.mapped('pack_operation_ids').unlink()
        quants = []
        # Mark as recompute pack needed
        if move.picking_id:  # pragma: no cover
            move.picking_id.recompute_pack_op = True

        merge_quants = move.reserved_quant_ids

        for quant_id in move.reserved_quant_ids.ids:
            move.write({'reserved_quant_ids': [[3, quant_id]]})

        # quants = move.reserved_quant_ids
        # super(StockMove, move).quants_unreserve()
        merge_quants.merge_stock_quants()

        for line in self.quants_lines.filtered('selected'):
            quants.append([line.quant, line.qty])
        self.env['stock.quant'].quants_reserve(quants, move)
        return {}

    def get_available_quants(self, move, location_search_key=None, track_no_search_key=None):
        domain = [
            ('location_id', 'child_of', move.location_id.id),
            ('product_id', '=', move.product_id.id),
            ('qty', '>', 0),
            '|',
            ('reservation_id', '=', False),
            ('reservation_id', '=', move.id)
        ]
        if location_search_key:
            domain.append(('location_id.display_name', 'ilike', location_search_key))
        if track_no_search_key:
            domain.append(('lot_id.ref', 'ilike', track_no_search_key))
        available_quants = self.env['stock.quant'].search(domain, order="lot_ref")
        return [{
            'quant': x.id,
            'quant_qty': x.qty,
            'quant_uom': x.product_uom_id.id,
            'lot_id': x.lot_id.id,
            'in_date': x.in_date,
            'package_id': x.package_id.id,
            'selected': x in move.reserved_quant_ids,
            'qty': x.qty if x in move.reserved_quant_ids else 0,
            'location_id': x.location_id.id,
        } for x in available_quants]

    # @api.model
    # def default_get(self, fields):
    #     res = super(movepickQuants, self).default_get(fields)
    #     move = self.env['stock.move'].browse(self.env.context['active_id'])
    #     quants_lines = self.get_available_quants(move)
    #     res.update({'quants_lines': quants_lines})
    #     res = self._convert_to_write(self._convert_to_cache(res))
    #     return res

    def action_update_available_quants(self):
        self.ensure_one()
        self.quants_lines = None
        quants_lines = self.get_available_quants(self.move_id, location_search_key=self.location_search_key,
                                                 track_no_search_key=self.track_no_search_key)
        self.update({'quants_lines': quants_lines})
        return {
            'type': 'ir.actions.act_window',
            'res_model': self._name,
            'res_id': self.id,
            'view_type': 'form',
            'view_mode': 'form',
            'target': 'new',
        }


class movepickQuantsLines(models.TransientModel):
    _name = 'move.pick.quants.lines'
    _rec_name = 'quant'

    @api.multi
    @api.onchange('selected')
    def onchange_selected(self):
        for record in self:
            if not record.selected:
                record.qty = False
            elif not record.qty:
                quant_qty = record.quant.qty
                remaining_qty = record.move_wizard.move_qty
                record.qty = (quant_qty if quant_qty < remaining_qty else
                              remaining_qty)

    move_wizard = fields.Many2one(
        comodel_name='move.pick.quants', string=u'移动', required=True,
        ondelete='cascade')
    quant = fields.Many2one(
        comodel_name='stock.quant', string=u'份', required=True,
        ondelete='cascade')
    quant_qty = fields.Float(string=u'份数量',related='quant.qty')
    quant_uom = fields.Many2one(
        comodel_name='product.uom', string=u'份单位',related='quant.product_uom_id')
    location_id = fields.Many2one(
        comodel_name='stock.location', string=u'库位',
        related='quant.location_id', readonly=True)
    lot_id = fields.Many2one(
        comodel_name='stock.production.lot', string=u'批次号',
        related='quant.lot_id', readonly=True,
        groups="stock.group_production_lot")
    in_date = fields.Date(
        string='Incoming Date', readonly=True)
    package_id = fields.Many2one(
        comodel_name='stock.quant.package', string=u'包',
        related='quant.package_id', readonly=True,
        groups="stock.group_tracking_lot")
    qty = fields.Float(
        string=u'数量', digits=dp.get_precision('Product Unit of Measure'))
    selected = fields.Boolean(string=u'选择')
